'''
coding:utf-8
:writingtime: 2022-6-26
:author: wanjun
:reference: 
:doi: 
:examiner: 
'''
from math import pow, fabs, exp, log
from Utilities.AutoGetOperator.selectPackage import get_func


Operator_IVQ_ROFS=get_func(r'Operators/OperationOperators/OperatorIVQROF.py','Operator_IVQ_ROFS')

class AcezelAlsina(Operator_IVQ_ROFS):


    def add(self, a1, a2, q=0, y=0, *waste1, **waste2):
        """
            funciton    : A-A算子，区间值广义正交模糊集的 和 运算
            a1          : 一个模糊集, 形式:（[x,y]，[x,y]）
            a2          : 一个模糊集, 形式:（[x,y]，[x,y]）
            return      : 加法结果, 形式:（[x,y]，[x,y]）
        """
        u_1_f, u_1_r, v_1_f, v_1_r = *a1[0], *a1[1]
        u_2_f, u_2_r, v_2_f, v_2_r = *a2[0], *a2[1]
        if q <= 0:
            q = self.q
        if y <= 0:
            y = self.x
        # AA 所定义的 add 法则
        u_f = (1 - exp(-(((-log(1 - u_1_f ** q)) ** y + (-log(1 - u_2_f ** q)) ** y) ** (1 / y)))) ** (1 / q)
        u_r = (1 - exp(-(((-log(1 - u_1_r ** q)) ** y + (-log(1 - u_2_r ** q)) ** y) ** (1 / y)))) ** (1 / q)
        v_f = (exp(-(((-log(v_1_f ** q)) ** y + (-log(v_2_f ** q)) ** y) ** (1 / y)))) ** (1 / q)
        v_r = (exp(-(((-log(v_1_r ** q)) ** y + (-log(v_2_r ** q)) ** y) ** (1 / y)))) ** (1 / q)
        return ([u_f, u_r], [v_f, v_r])

    def multi(self, a1, a2, q=0, y=0, *waste1, **waste2):
        """
            funciton    : A-A算子，区间值广义正交模糊集的 积 运算
            a1          : 一个模糊集, 形式:（[x,y]，[x,y]）
            a2          : 一个模糊集, 形式:（[x,y]，[x,y]）
            return      : 乘法结果, 形式:（[x,y]，[x,y]）
        """
        u_1_f, u_1_r, v_1_f, v_1_r = *a1[0], *a1[1]
        u_2_f, u_2_r, v_2_f, v_2_r = *a2[0], *a2[1]
        if q <= 0:
            q = self.q
        if y <= 0:
            y = self.x
        # AA 所定义的 multi 法则
        u_f = (exp(-(((-log(u_1_f ** q)) ** y + (-log(u_2_f ** q)) ** y) ** (1 / y)))) ** (1 / q)
        u_r = (exp(-(((-log(u_1_r ** q)) ** y + (-log(u_2_r ** q)) ** y) ** (1 / y)))) ** (1 / q)
        v_f = (1 - exp(-(((-log(1 - v_1_f ** q)) ** y + (-log(1 - v_2_f ** q)) ** y) ** (1 / y)))) ** (1 / q)
        v_r = (1 - exp(-(((-log(1 - v_1_r ** q)) ** y + (-log(1 - v_2_r ** q)) ** y) ** (1 / y)))) ** (1 / q)
        return ([u_f, u_r], [v_f, v_r])

    def kmulti(self, a, k, q=0, y=0, *waste1, **waste2):
        """
            function : A-A算子，区间值广义正交模糊集的 数乘 运算
            a        : 一个模糊集, 形式:（[x,y]，[x,y]）
            k        : ka 的常数 k
            return   : 数乘 运算法则 的值，形式：（[x,y]，[x,y]）
        """
        u_a_f, u_a_r, v_a_f, v_a_r = *a[0], *a[1]
        if q <= 0:
            q = self.q
        if y <= 0:
            y = self.x
        u_f = (1 - exp(-(k * ((-log(1 - u_a_f ** q)) ** y)) ** (1 / y))) ** (1 / q)
        u_r = (1 - exp(-(k * ((-log(1 - u_a_r ** q)) ** y)) ** (1 / y))) ** (1 / q)
        v_f = (exp(-(k * ((-log(v_a_f ** q)) ** y)) ** (1 / y))) ** (1 / q)
        v_r = (exp(-(k * ((-log(v_a_r ** q)) ** y)) ** (1 / y))) ** (1 / q)
        return ([u_f, u_r], [v_f, v_r])

    def pow(self, a, k, q=0, y=0, *waste1, **waste2):
        """
            function : A-A算子，区间值广义正交模糊集的 乘方 运算
            a        : 一个模糊集, 形式:（[x,y]，[x,y]）
            k        : ka 的常数 k
            return   : 乘方 运算法则 的值，形式：（[x,y]，[x,y]）
        """
        u_a_f, u_a_r, v_a_f, v_a_r = *a[0], *a[1]
        if q <= 0:
            q = self.q
        if y <= 0:
            y = self.x
        # AA 算子中定义的乘方运算
        u_f = (exp(-(k * ((-log(u_a_f ** q)) ** y)) ** (1 / y))) ** (1 / q)
        u_r = (exp(-(k * ((-log(u_a_r ** q)) ** y)) ** (1 / y))) ** (1 / q)
        v_f = (1 - exp(-(k * ((-log(1 - v_a_f ** q)) ** y)) ** (1 / y))) ** (1 / q)
        v_r = (1 - exp(-(k * ((-log(1 - v_a_r ** q)) ** y)) ** (1 / y))) ** (1 / q)

        return ([u_f, u_r], [v_f, v_r])



class AcezelAlsinaA(AcezelAlsina):

    def getResult(self):
        '''
        function：AcezelAlsina基础的算数平均公式
        :return: AcezelAlsina的AA公式计算的结果
        '''
        result=self.data_list[0]
        for i in range(1,len(self.data_list)):
            result=self.add(result,self.data_list[i])
        result=self.kmulti(result,1/len(self.data_list))

        return result

class AcezelAlsinaGA(AcezelAlsina):

    def getResult(self):
        '''
        function：AcezelAlsina基础的算数平均公式
        :return: AcezelAlsina的GA公式计算的结果
        '''
        result = self.data_list[0]
        for i in range(1, len(self.data_list)):
            result = self.multi(result, self.data_list[i])
        result = self.pow(result, 1 / len(self.data_list))

        return result

class AcezelAlsinaWA(AcezelAlsina):

    def getResult(self):
        '''
        function：AcezelAlsina的基础的加权算数平均公式
        :return: WAA公式计算的结果
        '''
        result = self.kmulti(self.data_list[0],self.weight_list[0])
        for i in range(1, len(self.data_list)):
            temp=self.kmulti(self.data_list[i],self.weight_list[i])
            result = self.add(result, temp)
        result = self.kmulti(result, 1 / len(self.data_list))

        return result

class AcezelAlsinaWGA(AcezelAlsina):

    def getResult(self):
        '''
        function：AcezelAlsina的基础的加权几何平均公式
        :return: AcezelAlsina的WA公式计算的结果
        '''
        result = self.pow(self.data_list[0],self.weight_list[0])
        for i in range(1, len(self.data_list)):
            temp=self.pow(self.data_list[i],self.weight_list[i])
            result = self.multi(result, temp)
        result = self.pow(result, 1 / len(self.data_list))

        return result

class AcezelAlsinaOWA(AcezelAlsina):

    def getResult(self):
        '''
        function：AcezelAlsina的基础的有序加权算数平均公式
        :return: AcezelAlsina的OWAA公式计算的结果
        '''
        # 将 数据集备份，将类中数据集属性 替换为 排序后的数据集
        data_list = self.data_list
        self.data_list = self.sortdata()

        result = self.kmulti(self.data_list[0],self.weight_list[0])
        for i in range(1, len(self.data_list)):
            temp=self.kmulti(self.data_list[i],self.weight_list[i])
            result = self.add(result, temp)
        result = self.kmulti(result, 1 / len(self.data_list))

        # 还原数据集
        self.data_list = data_list
        return result


if __name__ == "__main__":
    data= [([0.85, 0.95], [0.1, 0.2]), ([0.8, 0.9], [0.1, 0.2]), ([0.85, 0.95], [0.1, 0.2]), ([0.7, 0.8], [0.2, 0.3]),
        ([0.4, 0.5], [0.5, 0.6])]
    weight_list = [0.1, 0.2, 0.3, 0.1, 0.3]
    result  = AcezelAlsinaGA(data)
    print(result.getResult())

